using System;
using System.Web.UI;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace fbasync.web.Controls
{
    
    public partial class Pager : BaseUserControl
    {
        #region Internal types

        class PagerLinkItem
        {
            private string  _text;
            private int     _startItem;
            private int     _itemPage;
            private bool    _current;

            public bool Current
            {
                get { return _current; }
                set { _current = value; }
            }

            public int StartItem
            {
                get { return _startItem; }
                set { _startItem = value;}
            }

            public int ItemPage
            {
                get { return _itemPage; }
                set { _itemPage = value;}
            }

            public string Text
            {
                get { return _text; }
                set { _text = value; }
            }

            public PagerLinkItem(string text, int startItem, int itemPage, bool current)
            {
                Text = text;
                StartItem = startItem;
                ItemPage = itemPage;
                Current = current;
            }
        }

        #endregion

        #region Fields
        private bool _dataBinded = false;

        private int _pageSize = 10;
        private int _pagesRange = 6;
        
        private string _linkTextFormat = "{0}";
        private string _firstPageText = "first";
        private string _lastPageText = "last";
        private string _nextPageText = "next";
        private string _prevPageText = "prev";

        #endregion

        #region Properties

        public string LinkTextFormat
        {
            get { return _linkTextFormat; }
            set { _linkTextFormat = value; }
        }

        public string FirstPageText
        {
            get 
            {
                if (String.IsNullOrEmpty(_firstPageText)) _firstPageText = GetString("DefaultFirstText");

                return _firstPageText; 
            }
            set { _firstPageText = value; }
        }

        public string LastPageText
        {
            get 
            {
                if (String.IsNullOrEmpty(_lastPageText)) _lastPageText = GetString("DefaultLastText");

                return _lastPageText; 
            }
            set { _lastPageText = value; }
        }

        public string NextPageText
        {
            get 
            {
                if (String.IsNullOrEmpty(_nextPageText)) _nextPageText = GetString("DefaultNextText");

                return _nextPageText; 
            }
            set { _nextPageText = value; }
        }

        public string PrevPageText
        {
            get 
            {
                if (String.IsNullOrEmpty(_prevPageText)) _prevPageText = GetString("DefaultPrevText");

                return _prevPageText; 
            }
            set { _prevPageText = value; }
        }

        public int PageSize
        {
            get { return _pageSize; }
            set { _pageSize = value; }
        }

        public int PagesRange
        {
            get { return _pagesRange; }
            set { _pagesRange = value; }
        }

        public int TotalItems
        {
            get 
            {
                object obj = ViewState["TotalItems"];
                if (obj == null)
                    return 0;
                else
                    return (int)ViewState["TotalItems"]; 
            }
            set { ViewState["TotalItems"] = value; }
        }

        public int StartItem
        {
            get 
            {
                object obj = ViewState["StartItem"];
                if (obj == null)
                    return 0;
                else 
                    return (int)ViewState["StartItem"]; 
            }
            set { ViewState["StartItem"] = value; }
        }

        public int CurrentPage
        {
            get 
            {
                object obj = ViewState["CurrentPage"];
                if (obj == null)
                    return 0;
                else 
                    return (int)ViewState["CurrentPage"]; 
            }
            protected set { ViewState["CurrentPage"] = value; }
        }

        #endregion

        #region Events

        public event EventHandler<PagerClickEventArgs> ItemClick;

        #endregion

        public override void DataBind()
        {
            uiRepeater.DataSource = null;

            base.DataBind();

            if (TotalItems <= 0)
                //there is nothing to do here
                return;
            if (_pageSize <= 0)
                throw new Exception(String.Format(GetString("errorInvalidPageSize"), ID));

            _dataBinded = true;

            List<PagerLinkItem> list = new List<PagerLinkItem>();

            int curPage;
            if (StartItem < 0)
            {
                curPage = Math.Max(StartItem + TotalItems, 0) / _pageSize;
            }
            else
            {
                curPage = Math.Min(StartItem, TotalItems) / _pageSize;
            }

            //updating CurentPage property
            CurrentPage = curPage;

            int lastPage = (TotalItems - 1) / _pageSize;
            int rangeBefore = _pagesRange / 2;
            int rangeAfter = _pagesRange - rangeBefore;

            int addToEnd = (rangeBefore > curPage) ? rangeBefore - curPage : 0;
            int addToStart = (rangeAfter + curPage > lastPage) ? rangeAfter + curPage - lastPage : 0;

            int pStart = (curPage > rangeBefore + addToStart) ? curPage - rangeBefore - addToStart : 0;
            int pEnd = (curPage + rangeAfter + addToEnd < lastPage) ? curPage + rangeAfter + addToEnd : lastPage;

            if (curPage > pStart)
            {
                list.Add(new PagerLinkItem(_firstPageText, 0, 0, false));
                list.Add(new PagerLinkItem(_prevPageText, (curPage - 1) * _pageSize, curPage - 1, false));
            }

            for (int i = pStart; i <= pEnd; i++)
            {
                list.Add(new PagerLinkItem(String.Format(_linkTextFormat, i + 1), i * _pageSize, i, (i == curPage)));
            }

            if (curPage < lastPage)
            {
                list.Add(new PagerLinkItem(_nextPageText, (curPage + 1) * _pageSize, curPage + 1, false));
                list.Add(new PagerLinkItem(_lastPageText, lastPage * _pageSize, lastPage, false));
            }
            
            uiRepeater.DataSource = list;
            uiRepeater.ItemDataBound += OnRepeaterItemDataBound;
            uiRepeater.DataBind();
        }

        protected override void OnPreRender(EventArgs e)
        {
            if (!_dataBinded)
                DataBind();

            base.OnPreRender(e);
        }

        protected void OnRepeaterItemDataBound(Object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                PagerLinkItem data = e.Item.DataItem as PagerLinkItem;
                LinkButton button = e.Item.FindControl("uiLinkButton") as LinkButton;
                Label label = e.Item.FindControl("uiLabel") as Label;
                HtmlInputHidden start = e.Item.FindControl("uiStartItem") as HtmlInputHidden;
                HtmlInputHidden page = e.Item.FindControl("uiPageNum") as HtmlInputHidden;

                if (data.Current) 
                {
                    button.Visible = false;
                    label.Text = data.Text;
                }
                else 
                {
                    label.Visible = false;
                    button.Text = data.Text;
                }

                start.Value = data.StartItem.ToString();
                page.Value = data.ItemPage.ToString();
            }
        }

        protected void OnRepeaterItemCommand(object sender, RepeaterCommandEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
            {
                HtmlInputHidden startC = e.Item.FindControl("uiStartItem") as HtmlInputHidden;
                HtmlInputHidden pageC = e.Item.FindControl("uiPageNum") as HtmlInputHidden;

                int start = int.Parse(startC.Value);
                int page = int.Parse(pageC.Value);

                RaiseItemClickEvent(start, page);
            }
        }

        protected void RaiseItemClickEvent(int start, int page)
        {
            // Copy to a temporary variable to be thread-safe.
            CurrentPage = page;
            StartItem = start;

            EventHandler<PagerClickEventArgs> temp = ItemClick;
            if (temp != null)
                temp(this, new PagerClickEventArgs(start,page));

            //EventHandler<Onc
        }

    }

    public class PagerClickEventArgs : EventArgs
    {
        private int _start;

        public int Start
        {
            get { return _start; }
            set { _start = value; }
        }

        private int _itemPage;

        public int ItemPage
        {
            get { return _itemPage; }
            set { _itemPage = value; }
        }

        public PagerClickEventArgs(int start, int page)
        {
            Start = start;
            ItemPage = page;
        }

    }

}